package com.typhoon.spring_jdbctemplate.vo;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用于保存分页信息和负责分页逻辑运算的类。<br />
 * <b>这个类不是线程安全的</b>
 * </p>
 * <p>
 * 使用方法： <br />
 * PageHolder&lt;Person&gt; pList=new PageHolder&lt;Person&gt;();<br />
 * QueryResultVO.setPageIndex();//当前页的页码<br />
 * QueryResultVO.setPageSize();//每页的大小<br />
 * <br />
 * QueryResultVO.setRowCount(dao.count(...));//获取数据库里的总记录数<br />
 * QueryResultVO.setList(dao.list(...));//从数据库获取当前页的数据<br />
 * <br />
 * QueryResultVO.addParam("category","5");//设置其他的url参数<br />
 * request.setAttribute("pageHolder",QueryResultVO);//放入request<br />
 * 至此，PageHolder的数据填充就完成了，下一步是在JSP页面内做显示<br />
 *
 * @author Jonney
 */
public class QueryResultVO<E> implements Serializable {

    private static final long serialVersionUID = -5245410061872947318L;

    protected static final transient int DEFAULT_MAX_PAGE_SIZE = 5000;

    protected static final transient int DEFAULT_PAGE_SIZE = 25;

    protected static final transient String DEFAULT_PARAM_ENCODING = "utf-8";

    /**
     * 当前页码
     */
    private int pageIndex;

    /**
     * 页大小
     */
    private int pageSize = DEFAULT_PAGE_SIZE;


    /**
     * 最大页大小
     */
    private int maxPageSize = DEFAULT_MAX_PAGE_SIZE;
    /**
     * 是否最后一页
     */
    private boolean lastPage = false;
    /**
     * 页数量
     */
    private int pageCount;

    /**
     * 行数量
     */
    private long rowCount;

    /**
     * 数据列表
     */
    private List<E> list;


    public QueryResultVO(){}

    /**
     * @param pageSize 页大小
     */
    public QueryResultVO(int pageSize) {
        this(pageSize, false);
    }

    /**
     * @param pageSize 页大小
     */
    public QueryResultVO(int pageSize, boolean pageSizeResetAble) {
        this.pageSize = pageSize;
    }

    /**
     * @param pageIndex 当前页码
     * @param pageSize  页大小
     */
    public QueryResultVO(int pageIndex, int pageSize) {
        this.pageIndex = pageIndex < 1 ? 1 : pageIndex;
        this.pageSize = pageSize;
    }

    /**
     * @return pageCount
     */
    public int getPageCount() {
        return pageCount;
    }

    /**
     * @return rowCount
     */
    public long getRowCount() {
        return rowCount;
    }

    /**
     * @param rowCount 要设置的 rowCount
     * @throws Exception
     */
    public void setRowCount(long rowCount) {
        this.rowCount = rowCount;
        int pageSize = getPageSize();
        try {
            pageCount = (int) ((rowCount - 1 + pageSize) / pageSize);
        } catch (ArithmeticException e) {
            throw new RuntimeException("Property pageSize has not set into PageHolder.");
        }
        if (pageCount > 0 && pageIndex > pageCount) {
            pageIndex = pageCount;
        }
    }

    /**
     * @return pageIndex
     */
    public int getPageIndex() {
        return pageIndex < 1 ? 1 : pageIndex;
    }

    public void setPageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    /**
     * @return pageSize
     */
    public int getPageSize() {
        if (pageSize > maxPageSize) {
            return maxPageSize;
        } else {
            return pageSize;
        }
    }

    public int getMaxPageSize() {
        return maxPageSize;
    }

    public void setMaxPageSize(int maxPageSize) {
        this.maxPageSize = maxPageSize;
    }

    /**
     * @return list
     */
    public List<E> getList() {
        return list;
    }

    /**
     * @param list 要设置的 list
     */
    public void setList(List<E> list) {
        this.list = list;
    }


    /**
     * 取当前页的第一行数据在数据库中的行号，在操作数据库的时候有用
     *
     * @return
     */
    public int getRowOffset() {
        return (getPageIndex() - 1) * getPageSize();
    }

    /**
     * 是否第一页
     *
     * @return
     */
    public boolean isFirstPage() {
        return getPageIndex() <= 1;
    }

    /**
     * 是否最后一页
     *
     * @return
     */
    public boolean isLastPage() {
        return lastPage ? lastPage : (getPageIndex() >= getPageCount());
    }

    public void setLastPage(boolean lastPage) {
        this.lastPage = lastPage;
    }

    public void setPageCount(int pageCount) {
        this.pageCount = pageCount;
    }
}
